package com.suyl.markbfbc.point;

import java.util.ArrayList;
import java.util.List;

/**
 * 判断点是否在多边形内部
 * Gis中常用
 */
public class CalFactory {
    /**
     * 调用计算方法
     *
     * @param point  待判断点
     * @param points 多边形定点位置续连续
     * @return true:内 false:外
     */
    public static boolean pointInPolygon(Point point, List<Point> points) {
        int nCount = points.size();
        boolean nCross = false;
        for (int i = 0; i < nCount; i++) {
            Point p1 = points.get(i);//当前节点
            Point p2 = points.get((i + 1) % nCount);//下一个节点
            // 求解 y=p.y 与 p1p2 的交点
            if (p1.getY() == p2.getY()) // p1p2 与 y=p0.y平行
                continue;
            if (point.getY() < Math.min(p1.getY(), p2.getY())) // 交点在p1p2延长线上
                continue;
            if (point.getY() >= Math.max(p1.getY(), p2.getY())) // 交点在p1p2延长线上
                continue;
            // 从P发射一条水平射线 求交点的 X 坐标 ------原理: ((p2.y-p1.y)/(p2.x-p1.x))=((y-p1.y)/(x-p1.x))
            //直线k值相等 交点y=p.y
            double x = (point.getY() - p1.getY()) * (p2.getX() - p1.getX()) / (p2.getY() - p1.getY()) + p1.getX();
            if (x > point.getX())
                nCross = !nCross; // 只统计,单边交点在内，双在外
        }
        return nCross;
    }

    public static void main(String[] args) {
        List list = new ArrayList();
        for (int i = 0; i < 10; i += 9) {
            for (int y = 0; y < 10; y += 9) {
                Point point = new Point(i, y);
                list.add(point);
            }
        }
        Point point = new Point(0.9, 8);
        System.out.println(CalFactory.pointInPolygon(point, list));
    }
}
